package com.example.service.impl;

import com.example.common.Result;
import com.example.dto.RoleMenuPermissionDTO;
import com.example.entity.Permission;
import com.example.entity.RoleMenu;
import com.example.entity.RolePermission;
import com.example.mapper.PermissionMapper;
import com.example.mapper.RoleMenuMapper;
import com.example.mapper.RolePermissionMapper;
import com.example.service.MenuPermissionMappingService;
import com.example.service.PermissionDependencyService;
import com.example.service.PermissionSyncService;
import com.example.service.RolePermissionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class RolePermissionServiceImpl implements RolePermissionService {

    @Autowired
    private RolePermissionMapper rolePermissionMapper;

    @Autowired
    private RoleMenuMapper roleMenuMapper;

    @Autowired
    private PermissionMapper permissionMapper;

    @Autowired
    private PermissionDependencyService permissionDependencyService;

    @Autowired
    private PermissionSyncService permissionSyncService;

    @Autowired
    private MenuPermissionMappingService menuPermissionMappingService;

    @Override
    @Transactional
    public Result<String> assignPermissionsToRole(Long roleId, List<Long> permissionIds) {
        try {
            // 先删除该角色的所有权限
            rolePermissionMapper.deleteByRoleId(roleId);

            // 如果权限ID列表不为空，则新增权限关联
            if (permissionIds != null && !permissionIds.isEmpty()) {
                // 解析权限依赖，获取完整的权限列表（包括父级权限）
                Set<Long> allPermissionIds = permissionDependencyService.resolvePermissionDependencies(permissionIds);

                // 为每个权限创建角色权限关联
                for (Long permissionId : allPermissionIds) {
                    RolePermission rolePermission = new RolePermission();
                    rolePermission.setRoleId(roleId);
                    rolePermission.setPermissionId(permissionId);
                    rolePermission.setCreateTime(LocalDateTime.now());
                    rolePermission.setDeleted(0);
                    rolePermissionMapper.insert(rolePermission);
                }

                // 使用权限同步服务自动分配相关菜单
                int syncedMenus = permissionSyncService.syncMenusForPermissions(roleId, new ArrayList<>(allPermissionIds));

                String message = "分配权限成功";
                if (allPermissionIds.size() > permissionIds.size()) {
                    message += "，已自动包含 " + (allPermissionIds.size() - permissionIds.size()) + " 个依赖权限";
                }
                if (syncedMenus > 0) {
                    message += "，已自动分配 " + syncedMenus + " 个相关菜单";
                }

                return Result.success(message);
            }

            return Result.success("分配权限成功");
        } catch (Exception e) {
            return Result.error("分配权限失败：" + e.getMessage());
        }
    }

    @Override
    @Transactional
    public Result<String> assignMenuAndPermissions(RoleMenuPermissionDTO dto) {
        try {
            StringBuilder resultMessage = new StringBuilder();
            int totalSyncedMenus = 0;
            int totalSyncedPermissions = 0;

            // 1. 分配菜单
            if (dto.getMenuIds() != null && !dto.getMenuIds().isEmpty()) {
                // 先删除角色的所有菜单
                roleMenuMapper.deleteByRoleId(dto.getRoleId());
                
                // 解析菜单依赖，包含父级菜单
                Set<Long> allMenuIds = permissionDependencyService.resolveMenuDependencies(dto.getMenuIds());
                
                // 分配菜单
                for (Long menuId : allMenuIds) {
                    RoleMenu roleMenu = new RoleMenu();
                    roleMenu.setRoleId(dto.getRoleId());
                    roleMenu.setMenuId(menuId);
                    roleMenu.setCreateTime(LocalDateTime.now());
                    roleMenu.setDeleted(0);
                    roleMenuMapper.insert(roleMenu);
                }
                
                resultMessage.append("分配菜单成功（").append(allMenuIds.size()).append("个）");
                
                // 如果启用自动绑定权限，则为菜单分配对应权限
                if (dto.getAutoBindPermissions()) {
                    int syncedPermissions = permissionSyncService.syncPermissionsForMenus(dto.getRoleId(), new ArrayList<>(allMenuIds));
                    totalSyncedPermissions += syncedPermissions;
                    if (syncedPermissions > 0) {
                        resultMessage.append("，自动分配权限 ").append(syncedPermissions).append(" 个");
                    }
                }
            }

            // 2. 分配权限
            if (dto.getPermissionIds() != null && !dto.getPermissionIds().isEmpty()) {
                // 获取当前角色已有的权限，避免重复删除
                List<RolePermission> existingRolePermissions = rolePermissionMapper.selectByRoleId(dto.getRoleId());
                Set<Long> existingPermissionIds = existingRolePermissions.stream()
                        .map(RolePermission::getPermissionId)
                        .collect(Collectors.toSet());

                // 解析权限依赖，获取完整的权限列表
                Set<Long> allPermissionIds = permissionDependencyService.resolvePermissionDependencies(dto.getPermissionIds());
                
                // 分配新权限
                int newPermissionCount = 0;
                for (Long permissionId : allPermissionIds) {
                    if (!existingPermissionIds.contains(permissionId)) {
                        RolePermission rolePermission = new RolePermission();
                        rolePermission.setRoleId(dto.getRoleId());
                        rolePermission.setPermissionId(permissionId);
                        rolePermission.setCreateTime(LocalDateTime.now());
                        rolePermission.setDeleted(0);
                        rolePermissionMapper.insert(rolePermission);
                        newPermissionCount++;
                    }
                }
                
                if (resultMessage.length() > 0) {
                    resultMessage.append("；");
                }
                resultMessage.append("分配权限成功（").append(newPermissionCount).append("个新增）");
                
                // 如果启用自动绑定菜单，则为权限分配对应菜单
                if (dto.getAutoBindMenus()) {
                    int syncedMenus = permissionSyncService.syncMenusForPermissions(dto.getRoleId(), new ArrayList<>(allPermissionIds));
                    totalSyncedMenus += syncedMenus;
                    if (syncedMenus > 0) {
                        resultMessage.append("，自动分配菜单 ").append(syncedMenus).append(" 个");
                    }
                }
            }

            return Result.success(resultMessage.toString());
        } catch (Exception e) {
            return Result.error("分配菜单权限失败：" + e.getMessage());
        }
    }

    @Override
    @Transactional
    public Result<String> assignMenusWithPermissions(Long roleId, List<Long> menuIds) {
        try {
            if (menuIds == null || menuIds.isEmpty()) {
                return Result.error("菜单列表不能为空");
            }

            // 1. 先删除角色的所有菜单
            roleMenuMapper.deleteByRoleId(roleId);
            
            // 2. 解析菜单依赖，包含父级菜单
            Set<Long> allMenuIds = permissionDependencyService.resolveMenuDependencies(menuIds);
            
            // 3. 分配菜单
            for (Long menuId : allMenuIds) {
                RoleMenu roleMenu = new RoleMenu();
                roleMenu.setRoleId(roleId);
                roleMenu.setMenuId(menuId);
                roleMenu.setCreateTime(LocalDateTime.now());
                roleMenu.setDeleted(0);
                roleMenuMapper.insert(roleMenu);
            }
            
            // 4. 自动分配菜单对应的权限
            int syncedPermissions = permissionSyncService.syncPermissionsForMenus(roleId, new ArrayList<>(allMenuIds));
            
            String message = "分配菜单成功（" + allMenuIds.size() + "个）";
            if (syncedPermissions > 0) {
                message += "，自动分配对应权限 " + syncedPermissions + " 个";
            }
            
            return Result.success(message);
        } catch (Exception e) {
            return Result.error("分配菜单权限失败：" + e.getMessage());
        }
    }

    /**
     * 检查并修复角色权限菜单一致性
     */
    public Result<String> checkAndFixConsistency(Long roleId) {
        try {
            String result = permissionSyncService.checkAndFixRolePermissionConsistency(roleId);
            return Result.success(result);
        } catch (Exception e) {
            return Result.error("检查权限一致性失败：" + e.getMessage());
        }
    }

    @Override
    public Result<List<Long>> getRolePermissions(Long roleId) {
        try {
            List<RolePermission> rolePermissions = rolePermissionMapper.selectByRoleId(roleId);
            List<Long> permissionIds = rolePermissions.stream()
                    .map(RolePermission::getPermissionId)
                    .collect(Collectors.toList());
            return Result.success(permissionIds);
        } catch (Exception e) {
            return Result.error("查询角色权限失败：" + e.getMessage());
        }
    }

    @Override
    @Transactional
    public Result<String> removeRolePermissions(Long roleId) {
        try {
            rolePermissionMapper.deleteByRoleId(roleId);
            return Result.success("删除角色权限成功");
        } catch (Exception e) {
            return Result.error("删除角色权限失败：" + e.getMessage());
        }
    }

    @Override
    @Transactional
    public Result<String> removePermissionRoles(Long permissionId) {
        try {
            rolePermissionMapper.deleteByPermissionId(permissionId);
            return Result.success("删除权限角色关联成功");
        } catch (Exception e) {
            return Result.error("删除权限角色关联失败：" + e.getMessage());
        }
    }
} 